package hr.ctg.domain.action.mjesto;

import hr.ctg.domain.action.gmaps.GoogleMapsAction;
import hr.ctg.domain.action.objekt.SearchParameters;
import hr.ctg.domain.model.Mjesto;
import hr.ctg.domain.model.Objekt;
import hr.ctg.domain.model.Posjet;
import hr.ctg.domain.model.Rola;
import hr.ctg.domain.model.TipObjekta;
import hr.ctg.service.dao.MjestoDAO;
import hr.ctg.service.dao.ObjektDAO;
import hr.ctg.service.dao.OtokDAO;
import hr.ctg.service.dao.PosjetDAO;
import hr.ctg.service.dao.SlikaDAO;
import hr.ctg.service.dao.TipObjektaDAO;

import java.sql.Date;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.faces.context.FacesContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.security.Identity;
import org.joda.time.DateTime;

@Name("mjestoDetailsAction")
@Scope(ScopeType.CONVERSATION)
public class MjestoDetailsAction {

	@In
	PosjetDAO posjetDAO;
	@In
	FacesContext facesContext;
	@In
	MjestoDAO mjestoDAO;
	@In
	OtokDAO otokDAO;
	@In
	ObjektDAO objektDAO;
	@In
	TipObjektaDAO tipObjektaDAO;
	@In(create = true)
	GoogleMapsAction googleMapsAction;
	@In
	SlikaDAO slikaDAO;
	@In
	SearchParameters searchParameters;
	@In
	Identity identity;

	@RequestParameter
	Integer idMjesta;
	@RequestParameter
	Integer idTipaObjekta;

	@Factory(value = "mjestoDetails", autoCreate = true)
	@Transactional
	public Mjesto getMjesto() {
		Mjesto mjesto;
		if (idMjesta == null) {
			if (searchParameters.getMjesto() != null) {
				idMjesta = searchParameters.getMjesto().getIdMjesta();
			}
		}

		if (idMjesta == null) {
			final String nazivMjesta = searchParameters.getNazivMjesta();
			mjesto = mjestoDAO.findByNaziv(nazivMjesta);
		} else {
			mjesto = mjestoDAO.find(idMjesta);
		}
		if (mjesto == null) {
			return null;
		}

		mjesto.setBrojPosjeta(mjestoDAO.findBrojPosjeta(mjesto.getIdMjesta()).intValue());

		// if (mjesto != null && mjesto.getLongituda() == null) {
		// final double[] coord = googleMapsAction.getLocation(mjesto
		// .getNaziv());
		// if (coord != null) {
		// mjesto.setLatituda(Double.valueOf(coord[0]));
		// mjesto.setLongituda(Double.valueOf(coord[1]));
		// mjesto.setZoom(Integer.valueOf(7));
		// mjestoDAO.merge(mjesto);
		// }
		// }
		if (mjesto != null) {
			mjesto.setBrojSlika(slikaDAO.findCountByIdMjesta(
					mjesto.getIdMjesta()).intValue());
		}
		return mjesto;
	}

	@Transactional
	public void registerMjestoVisit() {
		if (idMjesta != null
				&& !identity.hasRole(Rola.Role.ADMIN.toString())
				&& (facesContext.getExternalContext().getSessionMap().get(
						"posjetMjesta" + idMjesta) == null || !((Boolean) facesContext
						.getExternalContext().getSessionMap().get(
								"posjetMjesta" + idMjesta)).booleanValue())) {
			final Mjesto mjesto = mjestoDAO.find(idMjesta);
			final java.util.Date currDate = new DateTime().toDateMidnight()
					.toDate();
			Posjet po = posjetDAO.findByMjestoDatumPosjete(idMjesta, currDate);
			if (po == null) {
				po = new Posjet();
				po.setMjesto(mjesto);
				po.setDatumPosjete(new Date(currDate.getTime()));
			}

			po.setBrojPosjeta(po.getBrojPosjeta() + 1);
			posjetDAO.merge(po);

			facesContext.getExternalContext().getSessionMap().put(
					"posjetMjesta" + idMjesta, Boolean.valueOf(true));

			if (mjesto.getOtok() != null) {
				Posjet pot = posjetDAO.findByOtokDatumPosjete(Integer
						.valueOf(mjesto.getOtok().getIdOtoka()), currDate);
				if (pot == null) {
					pot = new Posjet();
					pot.setOtok(otokDAO.find(Integer.valueOf(mjesto.getOtok()
							.getIdOtoka())));
					pot.setDatumPosjete(new Date(currDate.getTime()));
				}

				pot.setBrojPosjeta(pot.getBrojPosjeta() + 1);
				posjetDAO.merge(pot);
			}
		}
	}

	public boolean hasTopObjekti() {
		return objektDAO.findCountByOcjenaBrojPosjetaIdMjesta(idMjesta) > 0L;
	}

	public boolean hasObjekti(final Integer idTipaObjekta) {
		return objektDAO.findCountByIdMjestaIdTipaObjekta(Integer
				.valueOf(getMjesto().getIdMjesta()), idTipaObjekta) > 0L;
	}

	@Factory("tipoviObjekataByMjesto")
	public List<TipObjekta> getTipoviObjekata() {
		final Mjesto mjesto = getMjesto();
		if (mjesto != null) {
			return tipObjektaDAO.findByIdMjesta(Integer.valueOf(mjesto
					.getIdMjesta()));
		}

		return null;
	}

	@SuppressWarnings("unchecked")
	@Factory("objektiByMjesto")
	@Begin(join = true)
	public List<Objekt> getObjekti() {
		if (idMjesta == null || idTipaObjekta == null) {
			return Collections.EMPTY_LIST;
		}
		final List<Objekt> l = objektDAO.findByIdMjestaIdTipaObjekta(idMjesta,
				idTipaObjekta);
		if (l.size() > 0) {
			List projections = objektDAO.findOBDBSByIdObjektaList(l);
			for (final Objekt objekt : l) {
				for (final Iterator<Object[]> localIterator2 = projections
						.iterator(); localIterator2.hasNext();) {
					final Object[] proj = localIterator2.next();
					if (proj[0].equals(objekt.getIdObjekta())) {
						objekt.setOcjena((Double) proj[1]);
						objekt.setBrojDojmova((Integer) proj[2]);
						objekt.setBrojSlika((Integer) proj[3]);
					}
				}
			}
		}
		return l;
	}

	public boolean hasObjekti() {
		return objektDAO.findCountByIdMjesta(idMjesta) > 0 ? true : false;
	}
}